package cn.yx.permission.remote.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.yx.common.core.enums.TrueFalseEnum;
import cn.yx.common.redis.service.RedisService;
import cn.yx.permission.cond.RoleCond;
import cn.yx.permission.dos.RolePermissionExtendDo;
import cn.yx.permission.dto.RoleDto;
import cn.yx.permission.mapper.RolePermissionMapper;
import cn.yx.permission.remote.constant.RolePermissionConstant;
import cn.yx.permission.remote.dto.RolePermissionRemoteDto;
import cn.yx.permission.remote.service.RolePermissionRemoteService;
import cn.yx.permission.service.RoleService;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboService;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>角色权限远程服务接口实现类</p>
 *
 * @author Wgssmart
 */
@DubboService
@Slf4j
public class RolePermissionRemoteServiceImpl implements RolePermissionRemoteService {

    private final RoleService roleService;

    private final RolePermissionMapper rolePermissionMapper;

    private final RedisService redisService;

    public RolePermissionRemoteServiceImpl(RoleService roleService, RolePermissionMapper rolePermissionMapper,
                                           RedisService redisService) {
        this.roleService = roleService;
        this.rolePermissionMapper = rolePermissionMapper;
        this.redisService = redisService;
    }

    @Override
    @SuppressWarnings({"unchecked"})
    public List<RolePermissionRemoteDto> listAll() {
        if (redisService.hasKey(RolePermissionConstant.ALL_ROLE_PERMISSION_CACHE_KEY)) {
            return (List<RolePermissionRemoteDto>) redisService.get(RolePermissionConstant.ALL_ROLE_PERMISSION_CACHE_KEY);
        }
        // 查询带有permission字段的RolePermission
        List<RolePermissionExtendDo> rolePermissionExtendDoList = rolePermissionMapper.selectRolePermission();
        if (CollectionUtil.isNotEmpty(rolePermissionExtendDoList)) {
            // 筛选出所有关联了权限的角色ID
            List<Long> roleIds = rolePermissionExtendDoList.stream().map(RolePermissionExtendDo::getRoleId).distinct().collect(Collectors.toList());
            List<RoleDto> roleDtoList = listRoleByIds(roleIds);
            List<RolePermissionRemoteDto> rolePermissionRemoteDtoList = buildRolePermissionRemoteDtoList(roleDtoList, rolePermissionExtendDoList);
            redisService.set(RolePermissionConstant.ALL_ROLE_PERMISSION_CACHE_KEY, rolePermissionRemoteDtoList);
            return rolePermissionRemoteDtoList;
        }
        return new ArrayList<>();
    }

    private List<RoleDto> listRoleByIds(List<Long> roleIds) {
        RoleCond roleCond = new RoleCond();
        roleCond.setIdIn(roleIds);
        roleCond.setIsActive(TrueFalseEnum.Y.getValue());
        return roleService.listAll(roleCond);
    }

    private List<RolePermissionRemoteDto> buildRolePermissionRemoteDtoList(
            List<RoleDto> roleDtoList, List<RolePermissionExtendDo> rolePermissionExtendDoList) {
        List<RolePermissionRemoteDto> rolePermissionRemoteDtoList = new ArrayList<>();
        for (RolePermissionExtendDo rolePermissionExtendDo : rolePermissionExtendDoList) {
            String permission = rolePermissionExtendDo.getPermission();
            Long roleId = rolePermissionExtendDo.getRoleId();
            RoleDto roleDto = roleDtoList.stream().filter(rd -> rd.getId().equals(roleId)).findFirst().orElse(null);
            if (Objects.nonNull(roleDto)) {
                RolePermissionRemoteDto rolePermissionRemoteDto = new RolePermissionRemoteDto();
                rolePermissionRemoteDto.setRole(roleDto.getName());
                rolePermissionRemoteDto.setPermission(permission);
                rolePermissionRemoteDtoList.add(rolePermissionRemoteDto);
            }
        }
        return rolePermissionRemoteDtoList;
    }

}
